/**
 * @file HZipEngine.cpp
 * @brief 压缩/解压缩引擎核心类实现
 * @details 实现了压缩和解压缩的核心功能
 */

#include "HZipEngine.h"
#include <Directory.h>
#include <Entry.h>
#include <Path.h>
#include <File.h>
#include <FindDirectory.h>
#include <Alert.h>
#include <stdio.h>
#include <string.h>

// 包含格式插件头文件
#include "../formats/FormatPlugin.h"
#include "../formats/ZipFormat.h"
#include "../formats/TarFormat.h"
#include "../formats/GzipFormat.h"
#include "../formats/Bzip2Format.h"
#include "../formats/ZstdFormat.h"

/**
 * @brief 构造函数
 */
HZipEngine::HZipEngine()
{
    // 初始化时不做任何操作
}

/**
 * @brief 析构函数
 */
HZipEngine::~HZipEngine()
{
    // 析构时不做任何操作
}

/**
 * @brief 压缩文件或目录
 * @param format 压缩格式（如"zip", "tar.gz"等）
 * @param sourcePath 源文件或目录路径
 * @param targetPath 目标压缩文件路径
 * @return 操作是否成功
 */
bool HZipEngine::Compress(const char *format, const char *sourcePath, const char *targetPath)
{
    // 检查参数
    if (format == NULL || sourcePath == NULL || targetPath == NULL)
    {
        printf("参数错误：格式、源路径和目标路径不能为空\n");
        return false;
    }

    // 检查格式是否支持
    if (!IsFormatSupported(format))
    {
        printf("不支持的压缩格式：%s\n", format);
        return false;
    }

    // 检查源路径是否存在
    BEntry sourceEntry(sourcePath);
    if (!sourceEntry.Exists())
    {
        printf("源文件或目录不存在：%s\n", sourcePath);
        return false;
    }

    // 获取适用的格式插件
    FormatPlugin *plugin = _GetPluginForFormat(format);
    if (plugin == NULL)
    {
        printf("无法获取格式插件：%s\n", format);
        return false;
    }

    // 执行压缩操作
    bool result = plugin->Compress(sourcePath, targetPath);
    if (!result)
    {
        printf("压缩操作失败\n");
    }

    return result;
}

/**
 * @brief 解压缩文件
 * @param sourcePath 源压缩文件路径
 * @param targetPath 目标解压目录
 * @return 操作是否成功
 */
bool HZipEngine::Extract(const char *sourcePath, const char *targetPath)
{
    // 检查参数
    if (sourcePath == NULL || targetPath == NULL)
    {
        printf("参数错误：源路径和目标路径不能为空\n");
        return false;
    }

    // 检查源文件是否存在
    BEntry sourceEntry(sourcePath);
    if (!sourceEntry.Exists() || sourceEntry.IsDirectory())
    {
        printf("源压缩文件不存在或不是文件：%s\n", sourcePath);
        return false;
    }

    // 检查目标目录是否存在，如果不存在则创建
    BEntry targetEntry(targetPath);
    if (!targetEntry.Exists())
    {
        BDirectory parent;
        BPath path(targetPath);
        status_t result = create_directory(targetPath, 0755);
        if (result != B_OK)
        {
            printf("无法创建目标目录：%s\n", targetPath);
            return false;
        }
    }
    else if (!targetEntry.IsDirectory())
    {
        printf("目标路径不是目录：%s\n", targetPath);
        return false;
    }

    // 根据文件扩展名获取格式
    BString format = _GetFormatFromExtension(sourcePath);
    if (format.IsEmpty())
    {
        printf("无法识别文件格式：%s\n", sourcePath);
        return false;
    }

    // 获取适用的格式插件
    FormatPlugin *plugin = _GetPluginForFormat(format.String());
    if (plugin == NULL)
    {
        printf("无法获取格式插件：%s\n", format.String());
        return false;
    }

    // 执行解压缩操作
    bool result = plugin->Extract(sourcePath, targetPath);
    if (!result)
    {
        printf("解压缩操作失败\n");
    }

    return result;
}

/**
 * @brief 获取支持的压缩格式列表
 * @return 格式列表字符串
 */
BString HZipEngine::GetSupportedFormats() const
{
    // 返回支持的格式列表
    return BString("zip, tar, tar.gz, tar.bz2, gz, bz2, zst, tar.zst");
}

/**
 * @brief 检查文件格式是否受支持
 * @param format 格式名称
 * @return 是否支持
 */
bool HZipEngine::IsFormatSupported(const char *format) const
{
    if (format == NULL)
    {
        return false;
    }

    // 检查是否是支持的格式
    if (strcmp(format, "zip") == 0 ||
        strcmp(format, "tar") == 0 ||
        strcmp(format, "tar.gz") == 0 ||
        strcmp(format, "tar.bz2") == 0 ||
        strcmp(format, "gz") == 0 ||
        strcmp(format, "bz2") == 0 ||
        strcmp(format, "zst") == 0 ||
        strcmp(format, "tar.zst") == 0)
    {
        return true;
    }

    return false;
}

/**
 * @brief 获取适用于指定格式的插件
 * @param format 格式名称
 * @return 插件指针，如果不支持则返回NULL
 */
FormatPlugin *HZipEngine::_GetPluginForFormat(const char *format) const
{
    // 根据格式名称返回对应的插件
    // 注意：这里简化处理，实际应用中可能需要更复杂的插件管理机制
    if (strcmp(format, "zip") == 0)
    {
        return new ZipFormat();
    }
    else if (strcmp(format, "tar") == 0)
    {
        return new TarFormat();
    }
    else if (strcmp(format, "tar.gz") == 0 || strcmp(format, "gz") == 0)
    {
        return new GzipFormat();
    }
    else if (strcmp(format, "tar.bz2") == 0 || strcmp(format, "bz2") == 0)
    {
        return new Bzip2Format();
    }
    else if (strcmp(format, "tar.zst") == 0 || strcmp(format, "zst") == 0)
    {
        return new ZstdFormat();
    }

    return NULL;
}

/**
 * @brief 根据文件扩展名获取格式
 * @param path 文件路径
 * @return 格式名称
 */
BString HZipEngine::_GetFormatFromExtension(const char *path) const
{
    if (path == NULL)
    {
        return BString("");
    }

    BString pathStr(path);

    // 检查各种扩展名
    if (pathStr.IFindLast(".zip") >= 0)
    {
        return BString("zip");
    }
    else if (pathStr.IFindLast(".tar.gz") >= 0 || pathStr.IFindLast(".tgz") >= 0)
    {
        return BString("tar.gz");
    }
    else if (pathStr.IFindLast(".tar.bz2") >= 0 || pathStr.IFindLast(".tbz2") >= 0)
    {
        return BString("tar.bz2");
    }
    else if (pathStr.IFindLast(".tar.zst") >= 0 || pathStr.IFindLast(".tzst") >= 0)
    {
        return BString("tar.zst");
    }
    else if (pathStr.IFindLast(".tar") >= 0)
    {
        return BString("tar");
    }
    else if (pathStr.IFindLast(".gz") >= 0)
    {
        return BString("gz");
    }
    else if (pathStr.IFindLast(".bz2") >= 0)
    {
        return BString("bz2");
    }
    else if (pathStr.IFindLast(".zst") >= 0)
    {
        return BString("zst");
    }

    return BString("");
}